home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / comobj.lisp / part05 < prev    next >
Encoding:
Internet Message Format  |  1987-07-30  |  42.8 KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i079:  Common Objects, Common Loops, Common Lisp, Part05/13
  5. Message-ID: <746@uunet.UU.NET>
  6. Date: 31 Jul 87 20:00:57 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 1422
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: Roy D'Souza <dsouza%hplabsc@hplabs.HP.COM>
  12. Posting-number: Volume 10, Issue 79
  13. Archive-name: comobj.lisp/Part05
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 5 (of 13)."
  22. # Contents:  meth-combi.l profmacs.l
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'meth-combi.l' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'meth-combi.l'\"
  26. else
  27. echo shar: Extracting \"'meth-combi.l'\" \(19923 characters\)
  28. sed "s/^X//" >'meth-combi.l' <<'END_OF_FILE'
  29. X;;; -*- Mode:LISP; Package:(PCL LISP 1000); Base:10; Syntax:Common-lisp -*-
  30. X;;;
  31. X;;; *************************************************************************
  32. X;;; Copyright (c) 1985 Xerox Corporation.  All rights reserved.
  33. X;;;
  34. X;;; Use and copying of this software and preparation of derivative works
  35. X;;; based upon this software are permitted.  Any distribution of this
  36. X;;; software or derivative works must comply with all applicable United
  37. X;;; States export control laws.
  38. X;;; 
  39. X;;; This software is made available AS IS, and Xerox Corporation makes no
  40. X;;; warranty about the software, its performance or its conformity to any
  41. X;;; specification.
  42. X;;; 
  43. X;;; Any person obtaining a copy of this software is requested to send their
  44. X;;; name and post office or electronic mail address to:
  45. X;;;   CommonLoops Coordinator
  46. X;;;   Xerox Artifical Intelligence Systems
  47. X;;;   2400 Hanover St.
  48. X;;;   Palo Alto, CA 94303
  49. X;;; (or send Arpanet mail to CommonLoops-Coordinator.pa@Xerox.arpa)
  50. X;;;
  51. X;;; Suggestions, comments and requests for improvements are also welcome.
  52. X;;; *************************************************************************
  53. X;;;
  54. X;;; User-defined method combination.  A first try.
  55. X;;;
  56. X;;; For compatibility with New Flavors, the following functions macros and
  57. X;;; variables have the same meaning.
  58. X;;;   define-simple-method-combination
  59. X;;;   define-method-combination
  60. X;;;   call-component-method
  61. X;;;   call-component-methods
  62. X;;;   *combined-method-arguments*
  63. X;;;   *combined-method-apply*
  64. X;;;
  65. X;;; In define-method-combination the arguments have the following meanings:
  66. X;;;
  67. X;;;   name             the name of this method combination type (symbol)
  68. X;;;   parameters       like a defmacro lambda list, it is matched with
  69. X;;;                    the value specified by the :method-combination
  70. X;;;                    option to make-specializable
  71. X;;;   method-patterns  a list of method-patterns specifications that are
  72. X;;;                    used to select some subset of the methods defined
  73. X;;;                    on the discriminator.  Each method pattern specifies
  74. X;;;                    a variable which is bound to a list of the methods
  75. X;;;                    it selects.
  76. X;;;   body             forms evaluated with the variables specified by
  77. X;;;                    the method patterns bound to produce the body of
  78. X;;;                    the combined method.  (see call-component-methods).
  79. X;;;
  80. X;;;  Body can be preceded by any number of options which take the form:
  81. X;;;    (<option-name> . <option-args>)
  82. X;;;
  83. X;;;  Currently, the defined options are:
  84. X;;;
  85. X;;;   :causes-combination-predicate
  86. X;;;       The only argument, should be a function of one argument.  It
  87. X;;;       will be called on a method (of the discriminator) and should
  88. X;;;       return T if that method causes the discriminator to combine
  89. X;;;       its methods.
  90. X;;;
  91. X;;; A method-patterns looks like:
  92. X;;;                    
  93. X;;;   (<var> <printer> <filter> <order> <pattern-1> <pattern-2> ..)
  94. X;;;
  95. X;;;      <var>      is the variable to which the selected methods
  96. X;;;                 are bound
  97. X;;;      <printer>  is ignored
  98. X;;;      <filter>   one of :every, :first, :last or :remove-duplicates
  99. X;;;      <order>    :most-specific-first or :most-specific-last
  100. X;;;
  101. X;;;      Methods matching any of the patterns are selected.  The patterns
  102. X;;;      are matched against the method-combination-options of the method
  103. X;;;      as specified in the defmeth.
  104. X;;; 
  105. X
  106. X(in-package 'pcl)
  107. X
  108. X;;;
  109. X;;; The method combination type of a particular method combination is stored
  110. X;;; as a symbol (the name of the method-combination) in the discriminator (in
  111. X;;; the method-combination-type slot).  Information about that particular
  112. X;;; method-combination-type is stored on the property list of the type symbol
  113. X;;; 
  114. X(defun get-method-combination-info (type &optional no-error-p)
  115. X  (or (get type 'method-combination)
  116. X      (if no-error-p () (error "No method combination named ~S." type))))
  117. X
  118. X(defun set-method-combination-info (type combiner predicate)
  119. X  (setf (get type 'method-combination) (list type combiner predicate)))
  120. X
  121. X(defmeth method-combiner ((discriminator method-combination-mixin))
  122. X  (cadr (get-method-combination-info
  123. X          (method-combination-type discriminator))))
  124. X
  125. X(defmeth method-causes-combination-predicate
  126. X         ((discriminator method-combination-mixin))
  127. X  (caddr (get-method-combination-info
  128. X           (method-combination-type discriminator))))
  129. X
  130. X
  131. X
  132. X
  133. X  ;;   
  134. X;;;;;; COMBINED-METHOD class
  135. X  ;;   
  136. X
  137. X(ndefstruct (combined-method (:class class)
  138. X                             (:include (method)))
  139. X  (deactivated-methods ()))
  140. X
  141. X(defmeth automatically-defined-p ((m combined-method)) (ignore m) t)
  142. X
  143. X(defmeth method-options ((m combined-method)) (ignore m) '(:combined))
  144. X                                                
  145. X(defmeth method-causes-combination-p ((m combined-method)) (ignore m) nil)
  146. X
  147. X(defmacro define-simple-method-combination (name operator
  148. X                                            &optional single-arg-is-value
  149. X                                                      (pretty-name
  150. X                                                        (string-downcase
  151. X                                                          name)))
  152. X  `(define-method-combination ,name
  153. X                              (&optional (order :most-specific-first))
  154. X             ((methods ,pretty-name :every order () (,name) :default))
  155. X     `(call-component-methods ,methods
  156. X                              :operator ,',operator
  157. X                              :single-arg-is-value ,',single-arg-is-value)))
  158. X
  159. X(defmacro define-method-combination (name parameters method-patterns
  160. X                                     &body body)
  161. X  (check-type parameters list)
  162. X  (check-type method-patterns (and list (not null)))
  163. X  (make-method-combination name parameters method-patterns body))
  164. X
  165. X
  166. X(defvar *combined-method-arguments*)
  167. X(defvar *combined-method-apply*)
  168. X(defvar *combined-method-template*)
  169. X
  170. X;;;
  171. X;;; Generate a form that calls a single method.
  172. X;;; With no keyword arguments, uses the value of *combined-methods-arguments*
  173. X;;; as the arguments to the call;
  174. X;;; With :ARGLIST, uses that instead;
  175. X;;; With :ARGLIST and :APPLY T, uses APPLY instead of FUNCALL
  176. X;;; With just :APPLY, it is the single argument to apply to.
  177. X;;;
  178. X;;; When called with *combined-method-template* bound, generates calls to
  179. X;;; the value of variables gotten from *combined-method-template* instead
  180. X;;; of to the actual methods themselves.  This is used to build templates
  181. X;;; for combined methods.
  182. X;;;
  183. X(defmacro call-component-method
  184. X          (method &key (apply nil apply-p)
  185. X                       (arglist 
  186. X                         (if apply-p
  187. X                             (prog1 (list apply) (setq apply t))
  188. X                             (prog1 *combined-method-arguments*
  189. X                                    (setq apply *combined-method-apply*)))))
  190. X  (call-component-method-internal method apply arglist))
  191. X
  192. X(defmacro call-component-methods (methods &key (operator 'progn)
  193. X                                               (single-arg-is-value nil))
  194. X  (call-component-methods-internal methods operator single-arg-is-value))
  195. X
  196. X(defmeth call-component-method-internal
  197. X         (method &optional (apply *combined-method-apply*)
  198. X                           (arglist *combined-method-arguments*))
  199. X  (when method
  200. X    `(,(if apply 'apply 'funcall)
  201. X      ,(if (boundp '*combined-method-template*)
  202. X       (let ((gensym (cdr (assq method *combined-method-template*))))
  203. X         (if gensym
  204. X         `(the function ,gensym)
  205. X         (error "*combined-method-template* out of sync??")))
  206. X       `',(method-function method))
  207. X      ,@arglist)))
  208. X  
  209. X(defmeth call-component-methods-internal (methods
  210. X                      operator single-arg-is-value)
  211. X  (when methods
  212. X    (if (and single-arg-is-value (null (cdr methods)))
  213. X    (call-component-method-internal (car methods))
  214. X    `(,operator
  215. X      ,@(iterate ((method in methods))
  216. X          (collect (call-component-method-internal method)))))))
  217. X
  218. X(defmeth call-component-method-equal (discriminator call-1 call-2)
  219. X  ;; If the options are the same (the part that the macros control the
  220. X  ;; processing of); and the individual calls are the same the part the
  221. X  ;; methods themselves control the processing of.
  222. X  (and (equal (cddr call-1) (cddr call-2))
  223. X       (if (eq (car call-1) 'call-component-method)
  224. X       (cond ((null (cadr call-1)) (null (cadr call-2)))
  225. X         ((null (cadr call-2)) (null (cadr call-1)))
  226. X         (t
  227. X          (call-component-method-equal-internal
  228. X            discriminator (cadr call-1) (cadr call-2))))
  229. X           (iterate ((meth-1 on (cadr call-1))
  230. X                     (meth-2 on (cadr call-2)))
  231. X         (when (or (and (cdr meth-1) (null (cdr meth-2)))
  232. X               (and (cdr meth-2) (null (cdr meth-1)))
  233. X               (null (call-component-method-equal-internal
  234. X                   discriminator (car meth-1) (car meth-2))))
  235. X           (return nil))))))
  236. X
  237. X(defmeth call-component-method-equal-internal (discriminator meth-1 meth-2)
  238. X  (ignore discriminator meth-1 meth-2)
  239. X  t)
  240. X
  241. X
  242. X
  243. X(defvar *method-combination-filters*
  244. X        '(:every :first :last :remove-duplicates))
  245. X
  246. X(defvar *method-combination-orders*
  247. X        '(:most-specific-first :most-specific-last))
  248. X
  249. X(defun make-method-combination (name parameters method-patterns body)
  250. X  (let ((causes-combination-predicate 'true)
  251. X        (combiner (make-symbol (string-append name " Method Combiner"))))
  252. X    ;; Error check and canonicalize the arguments.
  253. X    (unless (symbolp name)
  254. X      (error "The name of a method combination type must be a symbol, but ~S~
  255. X            was specified."
  256. X             name))
  257. X    ;; Check the various sub-parts of each method-patterns.  Canonicalize
  258. X    ;; each method-pattern by adding the () pattern to it if it has no
  259. X    ;; other patterns.
  260. X    (iterate ((method-patterns-loc on method-patterns))
  261. X      (destructuring-bind (var printer filter order . patterns)
  262. X                          (car method-patterns-loc)
  263. X        (check-symbol-variability var "bind (in a method-patterns)")
  264. X        (or (null (keywordp filter))
  265. X            (memq filter *method-combination-filters*)
  266. X            (error "A method-patterns filter must be one of: ~S~%not ~S."
  267. X                   *method-combination-filters* filter))
  268. X        (or (null (keywordp order))
  269. X            (memq order *method-combination-orders*)
  270. X            (error "A method-patterns order must be one of: ~S~%not ~S."
  271. X                   *method-combination-orders* filter))
  272. X        (if (null patterns)
  273. X            (setf (car method-patterns-loc)
  274. X                  (append (car method-patterns-loc) (list nil)))
  275. X            (iterate ((pattern in patterns))
  276. X              (or (listp pattern)
  277. X                  (eq pattern ':default)
  278. X                  (error "A method-pattern must be a list.~%~
  279. X                         In the method-patterns ~S, ~S is an invalid pattern."
  280. X                         (car method-patterns-loc) pattern))))))
  281. X    (iterate ()
  282. X      (while (and body (listp (car body))))
  283. X      (case (caar body)
  284. X        (:causes-combination-predicate
  285. X          (setq causes-combination-predicate (cadr (pop body))))
  286. X        (otherwise (return))))
  287. X
  288. X    `(progn 
  289. X       ,(make-combiner-definer
  290. X          combiner name parameters method-patterns body)
  291. X       (setf (get ',name 'combined-method-templates) ())
  292. X       (set-method-combination-info ',name
  293. X                                    ',combiner
  294. X                                    ',causes-combination-predicate))))
  295. X
  296. X(defun make-combiner-definer
  297. X       (combiner name parameters method-patterns body)
  298. X  (ignore name)
  299. X  `(defun ,combiner (.discriminator. .methods. .params.)
  300. X     .discriminator.
  301. X     (apply
  302. X       #'(lambda ,parameters
  303. X           (let ,(iterate (((var) in method-patterns)) (collect `(,var nil)))
  304. X             (do ((.method. (pop .methods.) (pop .methods.)))
  305. X                 ((null .method.))
  306. X               (cond 
  307. X                 ,@(iterate (((var nil fil ord . pats) in method-patterns))
  308. X                     (collect
  309. X               `((and ,(ecase fil
  310. X                 (:first
  311. X                   `(if (eq ,ord :most-specific-first)
  312. X                    (null ,var)
  313. X                    't))
  314. X                 (:last
  315. X                   `(if (eq ,ord :most-specific-first)
  316. X                    t
  317. X                    (null ,var)))
  318. X                 (:every
  319. X                   't))
  320. X                  (method-matches-patterns-p .method. ',pats))
  321. X                         (push .method. ,var))))))
  322. X         ,@(iterate (((var nil fil ord) in method-patterns))
  323. X         (cond ((memq fil '(:first :last))
  324. X            (collect `(setq ,var (car ,var))))
  325. X               ((eq ord ':most-specific-first)
  326. X            (collect `(setq ,var (nreverse ,var))))))
  327. X             ,@body))
  328. X       .params.)))
  329. X
  330. X
  331. X(defmeth method-matches-patterns-p (method patterns)
  332. X  (iterate ((pattern in patterns))
  333. X    (when (method-matches-pattern-p method pattern)
  334. X      (return t))))
  335. X
  336. X(defmeth method-matches-pattern-p (method pattern)
  337. X  (iterate ((pats = pattern (cdr pats))
  338. X            (opts = (method-options method) (cdr opts)))
  339. X    (if (symbolp pats)
  340. X        ;; Special case this because it means we have to blow out of
  341. X        ;; iterate.  Should iterate should know about dotted lists.
  342. X        (return (or (eq pats '*) (eq pats opts)))
  343. X        (unless (or (eq (car pats) '*)
  344. X                    (equal (car pats) (car opts)))
  345. X          (return nil)))    
  346. X    (finally (return t))))
  347. X
  348. X(defun patterns-keywords (patterns)
  349. X  (let ((keywords ()))
  350. X    (iterate ((pattern in patterns))
  351. X      (iterate ((elem in pattern))
  352. X        (when (keywordp elem) (push elem keywords))))
  353. X    keywords))
  354. X
  355. X(defun check-symbol-variability (symbol verb)
  356. X  (cond ((not (symbolp symbol))
  357. X         (error "Attempt to ~A ~S which is not a symbol" verb symbol))
  358. X        ((or (null symbol) (eq symbol 't))
  359. X         (error "Attempt to ~A ~S" verb symbol))
  360. X        ((eq (symbol-package symbol) (find-package 'keyword))
  361. X         (error "Attempt to ~A ~S, which is a keyword" verb symbol))
  362. X        ((constantp symbol)
  363. X         (error "Attempt to ~A ~S, which is a constant" verb symbol))))
  364. X
  365. X(defun cpl-filter-= (cpl1 cpl2 discriminator)
  366. X  (macrolet ((has-method-on-discriminator-p (class)
  367. X           `(memq discriminator (class-direct-discriminators ,class))))
  368. X    (prog ()
  369. X       restart
  370. X          (cond ((null cpl1)
  371. X         (if (null cpl2)
  372. X             (return t)
  373. X             (return nil)))
  374. X                ((null cpl2)
  375. X                 (return nil)))
  376. X          (unless (has-method-on-discriminator-p (car cpl1))
  377. X            (pop cpl1)
  378. X            (go restart))
  379. X          (unless (has-method-on-discriminator-p (car cpl2))
  380. X            (pop cpl2)
  381. X            (go restart))
  382. X          (if (neq (pop cpl1) (pop cpl2))
  383. X              (return nil)
  384. X          (go restart)))))
  385. X
  386. X
  387. X;;;   class-discriminators-which-combine-methods
  388. X;;;   discriminator-methods-combine-p
  389. X
  390. X(defmeth combine-methods ((class class) &optional discriminators)
  391. X  (let ((cpl (class-class-precedence-list class))
  392. X        (method nil)
  393. X        (method-cpl nil)
  394. X        (combined-method nil))
  395. X  
  396. X    (iterate ((disc in discriminators))
  397. X      (setq method (lookup-method disc class)
  398. X        method-cpl (and method
  399. X                (not (combined-method-p method))
  400. X                (class-class-precedence-list
  401. X                  (car (method-type-specifiers method)))))
  402. X      (unless (cpl-filter-= cpl method-cpl disc)
  403. X    (dolist (other-method (discriminator-methods disc))
  404. X      (when (and (combined-method-p other-method)
  405. X             (eq (car (method-type-specifiers other-method))
  406. X             class))
  407. X        (remove-method disc other-method)))
  408. X    (multiple-value-bind (arguments apply-p body)
  409. X        (combine-methods-internal class disc cpl)
  410. X      (setq combined-method 
  411. X        (make 'combined-method
  412. X              :function (compile-combined-method
  413. X                  disc arguments apply-p body)
  414. X              :arglist arguments
  415. X              :type-specifiers (cons class
  416. X                         (cdr (method-type-specifiers
  417. X                            method)))))
  418. X      (add-method disc combined-method nil))))))
  419. X
  420. X(defmeth combine-methods-internal (class discriminator cpl)
  421. X  (ignore class)
  422. X  (let ((methods (iterate ((c in cpl))
  423. X                   (join
  424. X             (iterate ((m in (discriminator-methods discriminator)))
  425. X               (when (and (eq (car (method-type-specifiers m)) c)
  426. X                  (not (combined-method-p m)))
  427. X             (collect m)))))))
  428. X    (multiple-value-bind (required restp)
  429. X        (compute-discriminating-function-arglist-info discriminator)
  430. X      (let ((*combined-method-arguments*
  431. X              (make-discriminating-function-arglist required restp))
  432. X            (*combined-method-apply* restp))
  433. X        (values *combined-method-arguments*
  434. X                *combined-method-apply*
  435. X                (funcall (method-combiner discriminator)
  436. X                         discriminator methods ()))))))
  437. X
  438. X
  439. X  ;;   
  440. X;;;;;; COMPILE-COMBINED-METHOD
  441. X  ;;   
  442. X
  443. X(defmeth compile-combined-method ((discriminator method-combination-mixin)
  444. X                                  *combined-method-arguments*
  445. X                                  *combined-method-apply*
  446. X                                  body)
  447. X  (multiple-value-bind (constructor methods-called)
  448. X      (compile-combined-method-internal discriminator body)
  449. X    (apply constructor (mapcar #'method-function methods-called))))
  450. X
  451. X(defmeth compile-combined-method-internal (discriminator body)
  452. X  (let* ((combination-type (method-combination-type discriminator))
  453. X         (templates (get combination-type 'combined-method-templates))
  454. X         (methods-called ())
  455. X         (walked-body 
  456. X           (walk-form body
  457. X             :walk-function
  458. X             #'(lambda (form context &aux temp)
  459. X                 (ignore context)
  460. X                 (values form
  461. X                         (and (eq context 'eval)
  462. X                              (listp form)
  463. X                              (setq temp (car form))
  464. X                              (cond ((eq temp 'call-component-method)
  465. X                                     (push (cadr form) methods-called))
  466. X                                    ((eq temp 'call-component-methods)
  467. X                                     (setq methods-called
  468. X                                           (append (cadr form)
  469. X                                                   methods-called))))))))))
  470. X    (setq methods-called (remove nil methods-called))
  471. X    (iterate ((entry in templates))
  472. X      (when (combined-method-equal discriminator (car entry) walked-body)
  473. X        (return (values (cdr entry) methods-called)))
  474. X      (finally    
  475. X        (let* ((*combined-method-template*
  476. X                 (iterate ((method in methods-called))
  477. X                   (collect (cons method (gensym)))))
  478. X               (new-constructor
  479. X                 (compile ()
  480. X                          `(lambda
  481. X                             ,(mapcar #'cdr *combined-method-template*)
  482. X                             #'(lambda ,*combined-method-arguments*
  483. X                                 ,(walk-form walked-body))))))
  484. X          (push (cons walked-body new-constructor)
  485. X                (get combination-type 'combined-method-templates))
  486. X          (return (values new-constructor methods-called)))))))
  487. X  
  488. X(defmeth combined-method-equal (discriminator comb-meth-1 comb-meth-2)
  489. X  (cond ((atom comb-meth-1) (eq comb-meth-1 comb-meth-2))
  490. X        ((memq (car comb-meth-1)
  491. X               '(call-component-method call-component-methods))
  492. X         (and (eq (car comb-meth-1) (car comb-meth-2))
  493. X              (call-component-method-equal
  494. X                discriminator comb-meth-1 comb-meth-2)))
  495. X        (t
  496. X         (and (combined-method-equal
  497. X                discriminator (car comb-meth-1) (car comb-meth-2))
  498. X              (combined-method-equal
  499. X                discriminator (cdr comb-meth-1) (cdr comb-meth-2))))))
  500. X
  501. X
  502. X
  503. X(defmeth discriminator-changed ((discriminator method-combination-mixin)
  504. X                (method combined-method)
  505. X                added-p)
  506. X  (ignore discriminator method added-p))
  507. X
  508. X(defmeth discriminator-changed ((discriminator method-combination-mixin)
  509. X                method
  510. X                added-p)
  511. X  (when (methods-combine-p discriminator)
  512. X    (let ((class (car (method-type-specifiers method))))
  513. X      (when (classp class)
  514. X    (labels ((walk-tree (class)
  515. X           (combine-methods class (list discriminator))
  516. X           (dolist (subclass (class-direct-subclasses class))
  517. X             (walk-tree subclass))))
  518. X      (walk-tree class)))))
  519. X  (run-super))
  520. X
  521. X
  522. END_OF_FILE
  523. if test 19923 -ne `wc -c <'meth-combi.l'`; then
  524.     echo shar: \"'meth-combi.l'\" unpacked with wrong size!
  525. fi
  526. # end of 'meth-combi.l'
  527. fi
  528. if test -f 'profmacs.l' -a "${1}" != "-c" ; then 
  529.   echo shar: Will not clobber existing file \"'profmacs.l'\"
  530. else
  531. echo shar: Extracting \"'profmacs.l'\" \(20279 characters\)
  532. sed "s/^X//" >'profmacs.l' <<'END_OF_FILE'
  533. X
  534. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  535. X;
  536. X; File:         profmacs.l
  537. X; SCCS:         %A% %G% %U%
  538. X; Description:  Macros For Profiling
  539. X; Author:       James Kempf, HP/DCC
  540. X; Created:      7-Feb-87
  541. X; Modified:     25-Feb-87 09:06:08 (James Kempf)
  542. X; Language:     Lisp
  543. X; Package:      TEST
  544. X;
  545. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  546. X
  547. X(in-package 'test)
  548. X(use-package 'lisp)
  549. X
  550. X;;Need COOL
  551. X
  552. X(require "co")
  553. X(use-package 'co)
  554. X
  555. X
  556. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  557. X;     System Dependent Customizations
  558. X;
  559. X;  Some systems will have special, hardware or software dependent profiling
  560. X;  packages. If your system has one, put it in here. Otherwise, the default
  561. X;  timing functions from CLtL will be used. In addition, the system dependent
  562. X;  function for garbage collection should be inserted, if your system 
  563. X;  requires garbage collection. Otherwise, no garbage collection will be done.
  564. X;
  565. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  566. X
  567. X;;warn-garbage-collect-Warn that no garbage collection function is in use.
  568. X
  569. X(defun warn-garbage-collect ()
  570. X  (warn 
  571. X    "~&********  Profiling Measurments Could Be Interrupted By Garbage Collection *******"
  572. X  )
  573. X) ;warn-garbage-collect
  574. X
  575. X;;*clock-increment-in-milliseconds*-Increment of the clock
  576. X
  577. X(defvar *clock-increment-in-milliseconds* 0)
  578. X
  579. X;;Use the 10 microsecond clock
  580. X
  581. X#+HP 
  582. X(eval-when (load eval)
  583. X  (require "measure")
  584. X  (setf (symbol-function 'get-time) (symbol-function measure:time10usec))
  585. X  (setf *clock-increment-in-milliseconds* 0.01)
  586. X  (setf (symbol-function 'do-garbage-collect) (symbol-function 'system:gc))
  587. X
  588. X)
  589. X
  590. X;;Default is to just use the functions from Steele
  591. X
  592. X#-HP
  593. X(eval-when (load eval)
  594. X  (setf (symbol-function 'get-time) (symbol-function 'get-internal-real-time))
  595. X  (setf *clock-increment-in-milliseconds* 
  596. X    (* (float (/ 1.0 internal-time-units-per-second)) 1000.0)
  597. X  )
  598. X  (setf (symbol-function 'do-garbage-collect) (symbol-function 'warn-garbage-collect))
  599. X
  600. X)
  601. X
  602. X;;Switch for Class Definition Syntax
  603. X
  604. X(defvar *define-type-switch* T)
  605. X
  606. X;;Vector containing names of types with zero, one, two, and
  607. X;;  three instance variables.
  608. X
  609. X(defvar *iv-defined-types* (make-array '(4 4) :initial-element NIL))
  610. X
  611. X;;Lists of results
  612. X
  613. X;;For type definition (iterations ivs parents time)
  614. X
  615. X(defvar *define-type-results* NIL)
  616. X
  617. X;;For instance creation (interations ivs parents time)
  618. X
  619. X(defvar *creation-results* NIL)
  620. X
  621. X;;For method definition (iterations preexisting time)
  622. X
  623. X(defvar *define-method-results* NIL)
  624. X
  625. X;;For messaging (iterations functions time)
  626. X
  627. X(defvar *messaging-results* NIL)
  628. X
  629. X;;For inherited messaging (iterations parents time)
  630. X
  631. X(defvar *inherited-messaging-results* NIL)
  632. X
  633. X;;These variables and macros are used for inserting the result of
  634. X;;  macroexpantion times into the calculations
  635. X
  636. X(defvar *macro-start-clock* 0)
  637. X(defvar *macro-end-clock* 0)
  638. X(defvar *macro-total-time* 0)
  639. X
  640. X(defmacro macro-start-clock ()
  641. X
  642. X  (setf *macro-start-clock* (get-time))
  643. X  NIL
  644. X)
  645. X
  646. X(defmacro macro-end-clock ()
  647. X
  648. X  (setf *macro-end-clock* (get-time))
  649. X  (setf *macro-total-time* (- *macro-end-clock* *macro-start-clock*))
  650. X  (setf *macro-end-clock* 0)
  651. X  (setf *macro-start-clock* 0)
  652. X
  653. X  NIL
  654. X)
  655. X
  656. X(defmacro macro-insert-sum ()
  657. X
  658. X  (let
  659. X    (
  660. X     (returned-sum *macro-total-time*)
  661. X    )
  662. X
  663. X    (setf *macro-total-time* 0)
  664. X    returned-sum
  665. X )
  666. X
  667. X)
  668. X
  669. X;;do-type-definition-Profile Type or Class Definition
  670. X
  671. X(defmacro do-type-definition (record variables parents)
  672. X
  673. X  (let
  674. X    (
  675. X      (iv-names NIL)
  676. X      (code NIL)
  677. X      (tname NIL)
  678. X      (pnames NIL)
  679. X    )
  680. X
  681. X    ;;Construct a new function symbol for this test
  682. X
  683. X    (push (gensym) *function-symbols*)
  684. X
  685. X    ;;Generate a list of instance variable names
  686. X
  687. X    (dotimes (i variables )
  688. X      (setf iv-names
  689. X        (list*
  690. X          (if *define-type-switch*
  691. X            `(:var ,(gentemp)) 
  692. X            (gentemp)
  693. X          )
  694. X          iv-names
  695. X        ) 
  696. X      )
  697. X    )
  698. X
  699. X    ;;Generate list of parent names
  700. X
  701. X    (dotimes (i parents)
  702. X      (setf pnames
  703. X        (list* 
  704. X          (if *define-type-switch*
  705. X            `(:inherit-from ,(nth i (aref *iv-defined-types* 0 0))) 
  706. X             (nth i (aref *iv-defined-types* 0 0))
  707. X          )
  708. X          pnames
  709. X        )
  710. X      )
  711. X    )
  712. X
  713. X    ;;Generate code for type definition    
  714. X
  715. X    (dotimes (i 20)
  716. X    
  717. X      ;;Generate the name for this type and
  718. X      ;;  push onto the appropriate list
  719. X
  720. X      (setf tname (gentemp))
  721. X
  722. X      (setf (aref *iv-defined-types* parents variables)
  723. X            (push tname (aref *iv-defined-types* parents variables))
  724. X      )
  725. X
  726. X      ;;Generate the type code
  727. X
  728. X      (push
  729. X        (if *define-type-switch*
  730. X          `(define-type ,tname
  731. X             ,@iv-names
  732. X             ,@pnames
  733. X           )
  734. X           `(ndefstruct 
  735. X             (,tname
  736. X               (:class class)
  737. X           ,pnames
  738. X             )
  739. X             ,@iv-names
  740. X           )
  741. X        ) ;if
  742. X
  743. X        code
  744. X
  745. X      ) ;push
  746. X
  747. X    )
  748. X
  749. X    ;;Return code, inserting prolog and cache heating
  750. X
  751. X  `(defun ,(first *function-symbols*) ()
  752. X    (let
  753. X       (
  754. X         (after 0)
  755. X         (before 0)
  756. X         (sum 0)
  757. X       )
  758. X
  759. X       (tagbody 
  760. X       again
  761. X
  762. X         (do-garbage-collect)
  763. X
  764. X         ,(if *define-type-switch*
  765. X           `(define-type ,(gentemp)
  766. X             ,@iv-names
  767. X             ,@pnames
  768. X            )
  769. X            `(ndefstruct 
  770. X              (,(gentemp)
  771. X               (:class class)
  772. X           ,pnames
  773. X             )
  774. X             ,@iv-names
  775. X           )
  776. X         ) ;if
  777. X
  778. X         (setf before (get-time))
  779. X         (macro-start-clock)
  780. X         ,@code
  781. X         (macro-end-clock)
  782. X         (setf after (get-time))
  783. X
  784. X         (setf sum (macro-insert-sum))
  785. X
  786. X
  787. X         (if (< (the integer after) (the integer before))
  788. X           (go again)
  789. X         )
  790. X       )
  791. X
  792. X       (if ,record
  793. X         (push (list 20 ,variables ,parents (- after before) sum) *define-type-results*)
  794. X       )
  795. X
  796. X      )
  797. X
  798. X    )
  799. X
  800. X   ) ;let
  801. X
  802. X) ;do-type-definition
  803. X
  804. X(setf (symbol-function 'do-type-definition-macro) (macro-function 'do-type-definition))
  805. X(compile 'do-type-definition-macro)
  806. X(setf (macro-function 'do-type-definition) (symbol-function 'do-type-definition-macro))
  807. X
  808. X;;do-instance-creation-Create instances of types as above
  809. X
  810. X(defmacro do-instance-creation (record ivs parents)
  811. X
  812. X  (let
  813. X    (
  814. X      (code NIL)
  815. X    )
  816. X
  817. X    ;;Generate a new function symbol
  818. X
  819. X    (push (gensym) *function-symbols*)
  820. X
  821. X    ;;Generate code to create
  822. X
  823. X    (dotimes (i 20)
  824. X
  825. X      (push
  826. X        `(make-instance ',(nth i (aref *iv-defined-types* parents ivs)))
  827. X        code
  828. X      )
  829. X
  830. X    ) ;dotimes
  831. X
  832. X    ;;Return code, inserting prolog and cache heating
  833. X
  834. X  `(defun ,(first *function-symbols*) ()
  835. X    (let
  836. X       (
  837. X         (after 0)
  838. X         (before 0)
  839. X       )
  840. X
  841. X       (tagbody
  842. X       again
  843. X
  844. X         (do-garbage-collect)
  845. X
  846. X         (make-instance ',(nth 1 (aref *iv-defined-types* parents ivs)))
  847. X
  848. X          (setf before (get-time))
  849. X          ,@code
  850. X          (setf after (get-time))
  851. X
  852. X      (if (< (the integer after) (the integer before))
  853. X            (go again)
  854. X          )
  855. X        )
  856. X      
  857. X        (if ,record
  858. X          (push (list 20 ,ivs ,parents (- after before)) *creation-results*)
  859. X        )
  860. X
  861. X      )
  862. X    )
  863. X
  864. X  ) ;let
  865. X
  866. X) ;do-instance-creation
  867. X
  868. X(setf (symbol-function 'do-instance-creation-macro) (macro-function 'do-instance-creation))
  869. X(compile 'do-instance-creation-macro)
  870. X(setf (macro-function 'do-instance-creation) (symbol-function 'do-instance-creation-macro))
  871. X
  872. X;;switch-define-types-Define types depending on switch
  873. X
  874. X(defmacro switch-define-types ( parent &rest t-list)
  875. X
  876. X  (let
  877. X    (
  878. X      (code NIL)
  879. X    )
  880. X
  881. X    (dolist (ty t-list)
  882. X      (push
  883. X        (if *define-type-switch*
  884. X          `(define-type ,ty ,@(if parent `((:inherit-from ,parent)) NIL))
  885. X          `(ndefstruct (,ty (:class class) ,@(if parent `((:include (,parent))) `() ) )  )
  886. X        )
  887. X        code
  888. X      )
  889. X    )
  890. X
  891. X    `(progn
  892. X       ,@code
  893. X    )
  894. X
  895. X  )
  896. X) ;switch-define-types
  897. X
  898. X;;switch-define-method-Define method depending on switch
  899. X
  900. X(defmacro switch-define-method (name)
  901. X
  902. X  (if *define-type-switch*
  903. X    `(define-method (,name ,(intern (symbol-name name) (find-package 'keyword)) ) () )
  904. X    `(defmeth ,(intern (symbol-name name) co::*keyword-standin-package*)
  905. X       ((.inner-self. ,name))
  906. X     )
  907. X  )
  908. X
  909. X) ;switch-define-method
  910. X
  911. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  912. X; 
  913. X; Define Types For Method Definition Tests and Make Instances
  914. X;
  915. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  916. X
  917. X;;For testing method definition and invocation with varying methods on
  918. X;;  discriminator
  919. X
  920. X(funcall 
  921. X  (compile () 
  922. X    `(lambda () (switch-define-types NIL temp0 temp1 temp2 temp3 temp4))
  923. X  )
  924. X)
  925. X
  926. X(setf temp0 (make-instance 'temp0))
  927. X(setf temp1 (make-instance 'temp1))
  928. X(setf temp2 (make-instance 'temp2))
  929. X(setf temp3 (make-instance 'temp3))
  930. X(setf temp4 (make-instance 'temp4))
  931. X
  932. X;;For testing method invocation of inherited methods
  933. X
  934. X(funcall 
  935. X  (compile () 
  936. X    `(lambda () (switch-define-types NIL g3f))
  937. X  )
  938. X)
  939. X
  940. X(funcall 
  941. X  (compile () 
  942. X    `(lambda () (switch-define-method g3f))
  943. X  )
  944. X)
  945. X
  946. X(funcall 
  947. X  (compile () 
  948. X    `(lambda () (switch-define-types g3f g2f))
  949. X  )
  950. X)
  951. X
  952. X(funcall 
  953. X  (compile () 
  954. X    `(lambda () (switch-define-method g2f))
  955. X  )
  956. X)
  957. X
  958. X(funcall 
  959. X  (compile () 
  960. X    `(lambda () (switch-define-types g2f g1f))
  961. X  )
  962. X)
  963. X
  964. X(funcall 
  965. X  (compile () 
  966. X    `(lambda () (switch-define-method g1f))
  967. X  )
  968. X)
  969. X
  970. X(funcall 
  971. X  (compile () 
  972. X    `(lambda () (switch-define-types g1f g0f))
  973. X  )
  974. X)
  975. X
  976. X(funcall 
  977. X  (compile () 
  978. X    `(lambda () (switch-define-method g0f))
  979. X  )
  980. X)
  981. X
  982. X;;Make an instance of g0f
  983. X
  984. X(setf g0f (make-instance 'g0f))
  985. X
  986. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  987. X
  988. X;;Method symbol List
  989. X
  990. X(defvar *list-of-method-symbols* NIL)
  991. X
  992. X;;do-method-definition-Do the method definition
  993. X
  994. X(defmacro do-method-definition (record  predefined fortype)
  995. X
  996. X  (let
  997. X    (
  998. X      (code NIL)
  999. X    )
  1000. X
  1001. X    ;;Generate a new function symbol
  1002. X
  1003. X    (push (gensym) *function-symbols*)
  1004. X
  1005. X    ;;Generate method symbols if necessary
  1006. X
  1007. X    (if (not *list-of-method-symbols*)
  1008. X
  1009. X      (dotimes (i 20)
  1010. X        (push (intern (format NIL "T~D" i) (find-package :keyword))
  1011. X          *list-of-method-symbols*
  1012. X        )
  1013. X      )
  1014. X    ) ;if
  1015. X
  1016. X    ;;Generate code for method definition
  1017. X    (dolist (l *list-of-method-symbols*)
  1018. X
  1019. X      (push 
  1020. X        (if *define-type-switch*
  1021. X          `(define-method (,fortype ,l) ()  ) 
  1022. X          `(defmeth ,(intern (symbol-name l) co::*keyword-standin-package*) 
  1023. X             ((.inner-self. ,fortype)) 
  1024. X           )
  1025. X         )
  1026. X         code
  1027. X      )
  1028. X
  1029. X    )
  1030. X
  1031. X    ;;Return code, inserting prolog and cache heating
  1032. X
  1033. X  `(defun ,(first *function-symbols*) ()
  1034. X    (let
  1035. X       (
  1036. X         (after 0)
  1037. X         (before 0)
  1038. X         (sum 0)
  1039. X       )
  1040. X
  1041. X       (tagbody
  1042. X       again
  1043. X         (do-garbage-collect)
  1044. X         ,(if *define-type-switch*
  1045. X           `(define-method (,fortype ,(gentemp)) ()  ) 
  1046. X           `(defmeth ,(gentemp) ((.inner-self. ,fortype)) )
  1047. X         )
  1048. X
  1049. X         (setf before (get-time))
  1050. X         (macro-start-clock)
  1051. X         ,@code
  1052. X     (macro-end-clock)
  1053. X         (setf after (get-time))
  1054. X
  1055. X         (setf sum (macro-insert-sum))
  1056. X
  1057. X         (if (< (the integer after) (the integer before))
  1058. X           (go again)
  1059. X         )
  1060. X       )
  1061. X
  1062. X       (if ,record
  1063. X         (push (list 20 ,predefined (- after before) sum) *define-method-results*)
  1064. X       )
  1065. X
  1066. X      )
  1067. X
  1068. X    )
  1069. X
  1070. X  ) ;let
  1071. X
  1072. X) ;do-method-definition
  1073. X
  1074. X(setf (symbol-function 'do-method-definition-macro) (macro-function 'do-method-definition))
  1075. X(compile 'do-method-definition-macro)
  1076. X(setf (macro-function 'do-method-definition) (symbol-function 'do-method-definition-macro))
  1077. X
  1078. X;;do-messaging-Messaging macro code construction
  1079. X
  1080. X(defmacro do-messaging (record predefined &rest type-list)
  1081. X
  1082. X  (let
  1083. X    (
  1084. X      (code NIL)
  1085. X    )
  1086. X
  1087. X    ;;Generate a new function symbol
  1088. X
  1089. X    (push (gensym) *function-symbols*)
  1090. X
  1091. X    ;;Push on 20 messagings
  1092. X
  1093. X    (dotimes (i 20)
  1094. X
  1095. X      ;;Message for each type      
  1096. X
  1097. X      (dolist (ty type-list)
  1098. X
  1099. X         (push 
  1100. X           (if *define-type-switch*
  1101. X             `(=> ,ty ,(first *list-of-method-symbols*))
  1102. X             `(,(intern 
  1103. X                (symbol-name (first *list-of-method-symbols*)) 
  1104. X                co::*keyword-standin-package*
  1105. X               )
  1106. X               ,ty
  1107. X              )
  1108. X            )
  1109. X            code
  1110. X
  1111. X         ) ;push
  1112. X
  1113. X      ) ;dolist
  1114. X
  1115. X    ) ;dotimes
  1116. X
  1117. X    ;;Return code, inserting prolog and hardware cache
  1118. X    ;;  heating to another message.
  1119. X
  1120. X  `(defun ,(first *function-symbols*) ()
  1121. X    (let
  1122. X       (
  1123. X         (after 0)
  1124. X         (before 0)
  1125. X         (sum 0)
  1126. X       )
  1127. X
  1128. X       (tagbody
  1129. X       again
  1130. X
  1131. X         (do-garbage-collect)
  1132. X
  1133. X         ,(if *define-type-switch*
  1134. X           `(=> ,(first type-list) ,(second *list-of-method-symbols*))
  1135. X           `(,(intern 
  1136. X              (symbol-name (second *list-of-method-symbols*)) 
  1137. X              co::*keyword-standin-package*
  1138. X             )
  1139. X             ,(first type-list)
  1140. X            )
  1141. X          )
  1142. X
  1143. X
  1144. X         (setf before (get-time))
  1145. X         (macro-start-clock)
  1146. X         ,@code
  1147. X         (macro-end-clock)
  1148. X         (setf after (get-time))
  1149. X
  1150. X         (setf sum (macro-insert-sum))
  1151. X
  1152. X         (if (< (the integer after) (the integer before))
  1153. X           (go again)
  1154. X         )
  1155. X       )
  1156. X
  1157. X       (if ,record
  1158. X          (push (list (* 20 ,(length type-list)) 
  1159. X              ,predefined
  1160. X                  (- after before)
  1161. X                      sum
  1162. X                 )
  1163. X                 *messaging-results*
  1164. X          )
  1165. X       )
  1166. X
  1167. X      )
  1168. X
  1169. X    )
  1170. X
  1171. X  ) ;let
  1172. X
  1173. X) ;do-messaging
  1174. X
  1175. X(setf (symbol-function 'do-messaging-macro) (macro-function 'do-messaging))
  1176. X(compile 'do-messaging-macro)
  1177. X(setf (macro-function 'do-messaging) (symbol-function 'do-messaging-macro))
  1178. X
  1179. X;;do-inherited-messaging-Generate code for profiling inherited messaging
  1180. X
  1181. X(defmacro do-inherited-messaging (record level method)
  1182. X
  1183. X  (let
  1184. X    (
  1185. X      (code NIL)
  1186. X    )
  1187. X
  1188. X    ;;Generate a new function symbol
  1189. X
  1190. X    (push (gensym) *function-symbols*)
  1191. X
  1192. X    ;;Push on 20 messagings
  1193. X
  1194. X    (dotimes (i 20)
  1195. X
  1196. X      (push 
  1197. X        (if *define-type-switch*
  1198. X          `(=> g0f ,(intern (symbol-name method) (find-package 'keyword)))
  1199. X          `(,(intern 
  1200. X               (symbol-name method) 
  1201. X               co::*keyword-standin-package*
  1202. X             )
  1203. X             g0f
  1204. X          )
  1205. X        )
  1206. X        code
  1207. X
  1208. X      ) ;push
  1209. X
  1210. X    ) ;dotimes
  1211. X
  1212. X    ;;Return code, inserting prolog and hardware cache
  1213. X    ;;  heating to another message.
  1214. X
  1215. X  `(defun ,(first *function-symbols*) ()
  1216. X    (let
  1217. X       (
  1218. X         (after 0)
  1219. X         (before 0)
  1220. X         (sum 0)
  1221. X       )
  1222. X
  1223. X       (tagbody
  1224. X       again
  1225. X
  1226. X         (do-garbage-collect)
  1227. X
  1228. X         ,(if *define-type-switch*
  1229. X           `(=> g0f ,(intern (symbol-name method) (find-package 'keyword)))
  1230. X           `(,(intern 
  1231. X              (symbol-name method) 
  1232. X              co::*keyword-standin-package*
  1233. X             )
  1234. X             g0f
  1235. X            )
  1236. X          )
  1237. X
  1238. X
  1239. X         (setf before (get-time))
  1240. X         (macro-start-clock)
  1241. X          ,@code
  1242. X         (macro-end-clock)
  1243. X         (setf after (get-time))
  1244. X
  1245. X         (setf sum (macro-insert-sum))
  1246. X
  1247. X         (if (< (the integer after) (the integer before))
  1248. X           (go again)
  1249. X         )
  1250. X       )
  1251. X
  1252. X       (if ,record
  1253. X         (push (list 20 ,level (- after before) sum) *inherited-messaging-results*)
  1254. X       )
  1255. X
  1256. X      )
  1257. X
  1258. X    )
  1259. X
  1260. X  ) ;let
  1261. X
  1262. X) ;do-inherited-messaging
  1263. X
  1264. X(setf (symbol-function 'do-inherited-messaging-macro) (macro-function 'do-inherited-messaging))
  1265. X(compile 'do-inherited-messaging-macro)
  1266. X(setf (macro-function 'do-inherited-messaging) (symbol-function 'do-inherited-messaging-macro))
  1267. X
  1268. X;;print-results-Print the results to the file
  1269. X
  1270. X(defun print-results (filename fromwho)
  1271. X
  1272. X  (with-open-file
  1273. X    (istream filename :direction :output 
  1274. X              :if-exists :append 
  1275. X              :if-does-not-exist :create
  1276. X    )
  1277. X    
  1278. X    (format istream "~%~%~A~%~%" fromwho)
  1279. X    (format istream "~%~%Times are in msec. Clock increment:~F~%~%" *clock-increment-in-milliseconds*)
  1280. X
  1281. X
  1282. X
  1283. X    (format istream "~1,8@T~1,8@T~1,8@TMacroexpand Times~%~%")
  1284. X    (format istream 
  1285. X            "Operation~1,8@TSlots~1,8@TParents~1,8@TIterations~1,8@TTotal Time~1,8@TTime per Call~%~%"
  1286. X    )
  1287. X    (dolist (l (reverse *define-type-results*))
  1288. X      (format istream 
  1289. X              "Define Type~1,8@T~D~1,8@T~D~1,8@T~D~1,8@T~1,8@T~8,2F~1,8@T~8,2F~%" 
  1290. X              (second l)
  1291. X              (third l)
  1292. X              (first l)
  1293. X              (* (fifth l) *clock-increment-in-milliseconds*)
  1294. X              (* (float (/ (fifth l) (first l))) *clock-increment-in-milliseconds*)
  1295. X       )
  1296. X    )
  1297. X    (format istream 
  1298. X            "~%~%Operation~1,8@TIterations~1,8@TFunctions~1,8@TTotal Time~1,8@TTime per Call~%~%"
  1299. X    )
  1300. X    (dolist (l (reverse *define-method-results*))
  1301. X      (format istream 
  1302. X              "Define Operation~1,8@T~D~1,8@T~D~1,8@T~1,8@T~8,2F~1,8@T~8,2F~%" 
  1303. X              (first l)
  1304. X              (second l)
  1305. X              (* (fourth l) *clock-increment-in-milliseconds*)
  1306. X              (* (float (/ (fourth l) (first l))) *clock-increment-in-milliseconds*)
  1307. X       )
  1308. X    )
  1309. X    (dolist (l (reverse *messaging-results*))
  1310. X      (format istream 
  1311. X              "Operation Invocation~1,8@T~D~1,8@T~D~1,8@T~1,8@T~8,2F~1,8@T~8,2F~%" 
  1312. X              (first l)
  1313. X              (second l)
  1314. X              (* (fourth l) *clock-increment-in-milliseconds*)
  1315. X              (* (float (/ (fourth l) (first l))) *clock-increment-in-milliseconds*)
  1316. X       )
  1317. X    )
  1318. X    (format istream "~|")
  1319. X
  1320. X
  1321. X    (format istream "~%~%~A~%~%" fromwho)
  1322. X    (format istream "~%~%All Times in msec~%~%")
  1323. X
  1324. X    (format istream "~1,8@T~1,8@T~1,8@TType Definition and Instance Creation~%~%")
  1325. X    (format istream 
  1326. X            "Operation~1,8@TSlots~1,8@TParents~1,8@TIterations~1,8@TTotal Time~1,8@TTime per Call~%~%"
  1327. X    )
  1328. X    (dolist (l (reverse *define-type-results*))
  1329. X      (format istream 
  1330. X              "Define Type~1,8@T~D~1,8@T~D~1,8@T~D~1,8@T~1,8@T~8,2F~1,8@T~8,2F~%" 
  1331. X              (second l)
  1332. X              (third l)
  1333. X              (first l)
  1334. X              (* (fourth l) *clock-increment-in-milliseconds*)
  1335. X              (* (float (/ (fourth l) (first l))) *clock-increment-in-milliseconds*)
  1336. X       )
  1337. X    )
  1338. X
  1339. X    (dolist (l (reverse *creation-results*))
  1340. X      (format istream 
  1341. X              "Create Instance~1,8@T~D~1,8@T~D~1,8@T~D~1,8@T~1,8@T~8,2F~1,8@T~8,2F~%" 
  1342. X              (second l)
  1343. X              (third l)
  1344. X              (first l)
  1345. X              (* (fourth l) *clock-increment-in-milliseconds*)
  1346. X              (* (float (/ (fourth l) (first l))) *clock-increment-in-milliseconds*)
  1347. X       )
  1348. X    )
  1349. X
  1350. X    (format istream "~%~%~1,8@T~1,8@TOperation Creation and Invocation~%~%")
  1351. X    (format istream 
  1352. X            "Operation~1,8@TIterations~1,8@TFunctions~1,8@TTotal Time~1,8@TTime per Call~%~%"
  1353. X    )
  1354. X    (dolist (l (reverse *define-method-results*))
  1355. X      (format istream 
  1356. X              "Define Operation~1,8@T~D~1,8@T~D~1,8@T~1,8@T~8,2F~1,8@T~8,2F~%" 
  1357. X              (first l)
  1358. X              (second l)
  1359. X              (* (third l) *clock-increment-in-milliseconds*)
  1360. X              (* (float (/ (third l) (first l))) *clock-increment-in-milliseconds*)
  1361. X       )
  1362. X    )
  1363. X
  1364. X    (dolist (l (reverse *messaging-results*))
  1365. X      (format istream 
  1366. X              "Operation Invocation~1,8@T~D~1,8@T~D~1,8@T~1,8@T~8,2F~1,8@T~8,2F~%" 
  1367. X              (first l)
  1368. X              (second l)
  1369. X              (* (third l) *clock-increment-in-milliseconds*)
  1370. X              (* (float (/ (third l) (first l))) *clock-increment-in-milliseconds*)
  1371. X       )
  1372. X    )
  1373. X
  1374. X    (format istream "~%~%~1,8@T~1,8@TInherited Operation Invocation~%~%")
  1375. X    (format istream 
  1376. X            "Operation~1,8@TIterations~1,8@TParents~1,8@TTotal Time~1,8@TTime per Call~%~%"
  1377. X    )
  1378. X
  1379. X    (dolist (l (reverse *inherited-messaging-results*))
  1380. X      (format istream 
  1381. X              "Operation Invocation~1,8@T~D~1,8@T~D~1,8@T~1,8@T~8,2F~1,8@T~8,2F~%" 
  1382. X              (first l)
  1383. X              (second l)
  1384. X              (* (third l) *clock-increment-in-milliseconds*)
  1385. X              (* (float (/ (third l) (first l))) *clock-increment-in-milliseconds*)
  1386. X       )
  1387. X    )
  1388. X    (format istream "~|")
  1389. X  ) ;with-open-file
  1390. X
  1391. X  (setf *define-type-results* NIL)
  1392. X  (setf *creation-results* NIL)
  1393. X  (setf *define-method-results* NIL)
  1394. X  (setf *messaging-results* NIL)
  1395. X  (setf *inherited-messaging-results* NIL)
  1396. X
  1397. X) ;print-results
  1398. X
  1399. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1400. X
  1401. X(provide "co-profmacs")
  1402. X
  1403. END_OF_FILE
  1404. if test 20279 -ne `wc -c <'profmacs.l'`; then
  1405.     echo shar: \"'profmacs.l'\" unpacked with wrong size!
  1406. fi
  1407. # end of 'profmacs.l'
  1408. fi
  1409. echo shar: End of archive 5 \(of 13\).
  1410. cp /dev/null ark5isdone
  1411. MISSING=""
  1412. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  1413.     if test ! -f ark${I}isdone ; then
  1414.     MISSING="${MISSING} ${I}"
  1415.     fi
  1416. done
  1417. if test "${MISSING}" = "" ; then
  1418.     echo You have unpacked all 13 archives.
  1419.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1420. else
  1421.     echo You still need to unpack the following archives:
  1422.     echo "        " ${MISSING}
  1423. fi
  1424. ##  End of shell archive.
  1425. exit 0
  1426. -- 
  1427.  
  1428. Rich $alz            "Anger is an energy"
  1429. Cronus Project, BBN Labs    rsalz@bbn.com
  1430. Moderator, comp.sources.unix    sources@uunet.uu.net
  1431.